/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package com.sun.jna.platform.win32;
import static com.sun.jna.platform.win32.WinBase.CREATE_FOR_IMPORT;
import static com.sun.jna.platform.win32.WinBase.FILE_DIR_DISALOWED;
import static com.sun.jna.platform.win32.WinBase.FILE_ENCRYPTABLE;
import static com.sun.jna.platform.win32.WinBase.FILE_IS_ENCRYPTED;
import static com.sun.jna.platform.win32.WinBase.FILE_READ_ONLY;
import static com.sun.jna.platform.win32.WinNT.DACL_SECURITY_INFORMATION;
import static com.sun.jna.platform.win32.WinNT.FILE_ALL_ACCESS;
import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_EXECUTE;
import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_READ;
import static com.sun.jna.platform.win32.WinNT.FILE_GENERIC_WRITE;
import static com.sun.jna.platform.win32.WinNT.GENERIC_ALL;
import static com.sun.jna.platform.win32.WinNT.GENERIC_EXECUTE;
import static com.sun.jna.platform.win32.WinNT.GENERIC_READ;
import static com.sun.jna.platform.win32.WinNT.GENERIC_WRITE;
import static com.sun.jna.platform.win32.WinNT.GROUP_SECURITY_INFORMATION;
import static com.sun.jna.platform.win32.WinNT.OWNER_SECURITY_INFORMATION;
import static com.sun.jna.platform.win32.WinNT.SACL_SECURITY_INFORMATION;
import static com.sun.jna.platform.win32.WinNT.SE_RESTORE_NAME;
import static com.sun.jna.platform.win32.WinNT.SE_SECURITY_NAME;
import static com.sun.jna.platform.win32.WinNT.TOKEN_ADJUST_PRIVILEGES;
import static com.sun.jna.platform.win32.WinNT.TOKEN_DUPLICATE;
import static com.sun.jna.platform.win32.WinNT.TOKEN_IMPERSONATE;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.LMAccess.USER_INFO_1;
import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC;
import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC;
import com.sun.jna.platform.win32.WinBase.FILETIME;
import com.sun.jna.platform.win32.WinBase.PROCESS_INFORMATION;
import com.sun.jna.platform.win32.WinBase.STARTUPINFO;
import com.sun.jna.platform.win32.WinDef.BOOL;
import com.sun.jna.platform.win32.WinDef.BOOLByReference;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
import com.sun.jna.platform.win32.WinNT.ACCESS_ALLOWED_ACE;
import com.sun.jna.platform.win32.WinNT.ACL;
import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD;
import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
import com.sun.jna.platform.win32.WinNT.PACLByReference;
import com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET;
import com.sun.jna.platform.win32.WinNT.PSID;
import com.sun.jna.platform.win32.WinNT.PSIDByReference;
import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR;
import com.sun.jna.platform.win32.WinNT.SECURITY_DESCRIPTOR_RELATIVE;
import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL;
import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES;
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
import com.sun.jna.platform.win32.WinNT.TOKEN_PRIVILEGES;
import com.sun.jna.platform.win32.WinNT.TOKEN_TYPE;
import com.sun.jna.platform.win32.WinNT.WELL_KNOWN_SID_TYPE;
import com.sun.jna.platform.win32.WinReg.HKEYByReference;
import com.sun.jna.platform.win32.Winsvc.SC_HANDLE;
import com.sun.jna.platform.win32.Winsvc.SC_STATUS_TYPE;
import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_PROCESS;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.ptr.ShortByReference;
import junit.framework.TestCase;
/**
* @author dblock[at]dblock[dot]org
*/
public class Advapi32Test extends TestCase {
private static final String EVERYONE = "S-1-1-0";
public static void main(String[] args) {
junit.textui.TestRunner.run(Advapi32Test.class);
}
// see https://github.com/twall/jna/issues/482
public void testNoDuplicateMethodsNames() {
Collection<String> dupSet = AbstractWin32TestSupport.detectDuplicateMethods(Advapi32.class);
if (dupSet.size() > 0) {
for (String name : new String[] {
// has several overloads by design since the output value can be several types of data
"RegQueryValueEx",
// has several overloads by design since the input value can be several types of data
"RegSetValueEx"
}) {
dupSet.remove(name);
}
}
assertTrue("Duplicate methods found: " + dupSet, dupSet.isEmpty());
}
public void testGetUserName() {
IntByReference len = new IntByReference();
assertFalse(Advapi32.INSTANCE.GetUserNameW(null, len));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
char[] buffer = new char[len.getValue()];
assertTrue(Advapi32.INSTANCE.GetUserNameW(buffer, len));
String username = Native.toString(buffer);
assertTrue(username.length() > 0);
}
public void testLookupAccountName() {
IntByReference pSid = new IntByReference(0);
IntByReference pDomain = new IntByReference(0);
PointerByReference peUse = new PointerByReference();
String accountName = "Administrator";
assertFalse(Advapi32.INSTANCE.LookupAccountName(
null, accountName, null, pSid, null, pDomain, peUse));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
assertTrue(pSid.getValue() > 0);
Memory sidMemory = new Memory(pSid.getValue());
PSID pSidMemory = new PSID(sidMemory);
char[] referencedDomainName = new char[pDomain.getValue() + 1];
assertTrue(Advapi32.INSTANCE.LookupAccountName(
null, accountName, pSidMemory, pSid, referencedDomainName, pDomain, peUse));
assertEquals(SID_NAME_USE.SidTypeUser, peUse.getPointer().getInt(0));
assertTrue(Native.toString(referencedDomainName).length() > 0);
}
public void testIsValidSid() {
String sidString = EVERYONE;
PSIDByReference sid = new PSIDByReference();
assertTrue("SID conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid));
PSID value = sid.getValue();
try {
assertTrue("Converted SID not valid: " + value, Advapi32.INSTANCE.IsValidSid(value));
int sidLength = Advapi32.INSTANCE.GetLengthSid(value);
assertTrue("Non positive sid length", sidLength > 0);
assertTrue("Invalid sid", Advapi32.INSTANCE.IsValidSid(value));
} finally {
Kernel32Util.freeLocalMemory(value.getPointer());
}
}
public void testEqualSid() {
String sidString = EVERYONE;
PSIDByReference sid1 = new PSIDByReference();
PSIDByReference sid2 = new PSIDByReference();
assertTrue("SID1 conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid1));
assertTrue("SID2 conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid2));
try {
assertTrue("Converted SID1 not valid", Advapi32.INSTANCE.IsValidSid(sid1.getValue()));
assertTrue("Converted SID2 not valid", Advapi32.INSTANCE.IsValidSid(sid2.getValue()));
assertTrue("Invalid sid", Advapi32.INSTANCE.EqualSid(sid1.getValue(), sid2.getValue()));
} finally {
Kernel32Util.freeLocalMemory(sid1.getValue().getPointer());
Kernel32Util.freeLocalMemory(sid2.getValue().getPointer());
}
}
public void testGetSidLength() {
String sidString = EVERYONE;
PSIDByReference sid = new PSIDByReference();
assertTrue("SID conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid));
PSID value = sid.getValue();
try {
assertEquals("Wrong SID length", 12, Advapi32.INSTANCE.GetLengthSid(value));
} finally {
Kernel32Util.freeLocalMemory(value.getPointer());
}
}
public void testLookupAccountSid() {
// get SID bytes
String sidString = EVERYONE;
PSIDByReference sid = new PSIDByReference();
assertTrue("Failed to create sid", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid));
PSID value = sid.getValue();
try {
int sidLength = Advapi32.INSTANCE.GetLengthSid(value);
assertTrue("Non-positive sid length", sidLength > 0);
// lookup account
IntByReference cchName = new IntByReference();
IntByReference cchReferencedDomainName = new IntByReference();
PointerByReference peUse = new PointerByReference();
assertFalse(Advapi32.INSTANCE.LookupAccountSid(null, value,
null, cchName, null, cchReferencedDomainName, peUse));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
assertTrue(cchName.getValue() > 0);
assertTrue(cchReferencedDomainName.getValue() > 0);
char[] referencedDomainName = new char[cchReferencedDomainName.getValue()];
char[] name = new char[cchName.getValue()];
assertTrue(Advapi32.INSTANCE.LookupAccountSid(null, value,
name, cchName, referencedDomainName, cchReferencedDomainName, peUse));
assertEquals(5, peUse.getPointer().getInt(0)); // SidTypeWellKnownGroup
String nameString = Native.toString(name);
String referencedDomainNameString = Native.toString(referencedDomainName);
assertTrue(nameString.length() > 0);
if(AbstractWin32TestSupport.isEnglishLocale) {
assertEquals("Everyone", nameString);
}
assertTrue(referencedDomainNameString.length() == 0);
} finally {
Kernel32Util.freeLocalMemory(value.getPointer());
}
}
public void testConvertSid() {
String sidString = EVERYONE;
PSIDByReference sid = new PSIDByReference();
assertTrue("Failed to convert SID string", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid));
PSID value = sid.getValue();
try {
PointerByReference convertedSidStringPtr = new PointerByReference();
assertTrue("Failed to convert SID string", Advapi32.INSTANCE.ConvertSidToStringSid(value, convertedSidStringPtr));
Pointer conv = convertedSidStringPtr.getValue();
try {
String convertedSidString = conv.getWideString(0);
assertEquals("Mismatched SID string", convertedSidString, sidString);
} finally {
Kernel32Util.freeLocalMemory(conv);
}
} finally {
Kernel32Util.freeLocalMemory(value.getPointer());
}
}
public void testLogonUser() {
HANDLEByReference phToken = new HANDLEByReference();
assertFalse(Advapi32.INSTANCE.LogonUser("AccountDoesntExist", ".", "passwordIsInvalid",
WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phToken));
assertTrue(W32Errors.ERROR_SUCCESS != Kernel32.INSTANCE.GetLastError());
}
public void testOpenThreadTokenNoToken() {
HANDLEByReference phToken = new HANDLEByReference();
HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread();
assertNotNull(threadHandle);
assertFalse(Advapi32.INSTANCE.OpenThreadToken(threadHandle,
WinNT.TOKEN_READ, false, phToken));
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
}
public void testOpenProcessToken() {
HANDLEByReference phToken = new HANDLEByReference();
try {
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
} finally {
Kernel32Util.closeHandleRef(phToken);
}
}
public void testOpenThreadOrProcessToken() {
HANDLEByReference phToken = new HANDLEByReference();
try {
HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread();
if (! Advapi32.INSTANCE.OpenThreadToken(threadHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, true, phToken)) {
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
}
} finally {
Kernel32Util.closeHandleRef(phToken);
}
}
public void testSetThreadTokenCurrentThread() {
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDup = new HANDLEByReference();
try {
HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread();
// See if thread has a token. If not, must duplicate process token and set thread token using that.
if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle,
WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) {
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle, WinNT.TOKEN_DUPLICATE, phToken));
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(),
WinNT.TOKEN_IMPERSONATE,
null,
WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
WinNT.TOKEN_TYPE.TokenImpersonation,
phTokenDup));
// Null sets on current thread
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDup.getValue()));
}
else {
//Null sets on current thread
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phToken.getValue()));
}
// Revert and cleanup
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null));
} finally {
Kernel32Util.closeHandleRefs(phToken, phTokenDup);
}
}
public void testSetThreadTokenThisThread() {
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDup = new HANDLEByReference();
try {
HANDLEByReference pthreadHandle = new HANDLEByReference();
pthreadHandle.setValue(Kernel32.INSTANCE.GetCurrentThread());
// See if thread has a token. If not, must duplicate process token and set thread token using that.
if (!Advapi32.INSTANCE.OpenThreadToken(pthreadHandle.getValue(),
WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY, false, phToken)) {
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE, phToken));
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(),
WinNT.TOKEN_IMPERSONATE,
null,
WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
WinNT.TOKEN_TYPE.TokenImpersonation,
phTokenDup));
// Use HANDLEByReference on this thread to test, should be good enough for API compatibility.
assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phTokenDup.getValue()));
}
else {
// Use HANDLEByReference on this thread to test, should be good enough for API compatibility.
assertTrue(Advapi32.INSTANCE.SetThreadToken(pthreadHandle, phToken.getValue()));
}
// Revert and cleanup
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, null));
} finally {
Kernel32Util.closeHandleRefs(phToken, phTokenDup);
}
}
public void testDuplicateToken() {
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDup = new HANDLEByReference();
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
try {
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
assertTrue(Advapi32.INSTANCE.DuplicateToken(phToken.getValue(),
WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, phTokenDup));
} finally {
Kernel32Util.closeHandleRefs(phTokenDup, phToken);
}
}
public void testDuplicateTokenEx() {
HANDLEByReference hExistingToken = new HANDLEByReference();
HANDLEByReference phNewToken = new HANDLEByReference();
try {
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, hExistingToken));
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(hExistingToken.getValue(),
WinNT.GENERIC_READ, null, SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous,
TOKEN_TYPE.TokenPrimary, phNewToken));
} finally {
Kernel32Util.closeHandleRefs(phNewToken, hExistingToken);
}
}
public void testGetTokenOwnerInformation() {
HANDLEByReference phToken = new HANDLEByReference();
try {
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
IntByReference tokenInformationLength = new IntByReference();
assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, null, 0, tokenInformationLength));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
WinNT.TOKEN_OWNER owner = new WinNT.TOKEN_OWNER(tokenInformationLength.getValue());
assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenOwner, owner,
tokenInformationLength.getValue(), tokenInformationLength));
assertTrue(tokenInformationLength.getValue() > 0);
assertTrue(Advapi32.INSTANCE.IsValidSid(owner.Owner));
int sidLength = Advapi32.INSTANCE.GetLengthSid(owner.Owner);
assertTrue(sidLength < tokenInformationLength.getValue());
assertTrue(sidLength > 0);
// System.out.println(Advapi32Util.convertSidToStringSid(owner.Owner));
} finally {
Kernel32Util.closeHandleRef(phToken);
}
}
public void testGetTokenUserInformation() {
HANDLEByReference phToken = new HANDLEByReference();
try {
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
IntByReference tokenInformationLength = new IntByReference();
assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenUser, null, 0, tokenInformationLength));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
WinNT.TOKEN_USER user = new WinNT.TOKEN_USER(tokenInformationLength.getValue());
assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenUser, user,
tokenInformationLength.getValue(), tokenInformationLength));
assertTrue(tokenInformationLength.getValue() > 0);
assertTrue(Advapi32.INSTANCE.IsValidSid(user.User.Sid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(user.User.Sid);
assertTrue(sidLength > 0);
assertTrue(sidLength < tokenInformationLength.getValue());
// System.out.println(Advapi32Util.convertSidToStringSid(user.User.Sid));
} finally {
Kernel32Util.closeHandleRef(phToken);
}
}
public void testGetTokenGroupsInformation() {
HANDLEByReference phToken = new HANDLEByReference();
try {
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken));
IntByReference tokenInformationLength = new IntByReference();
assertFalse(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, null, 0, tokenInformationLength));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(tokenInformationLength.getValue());
assertTrue(Advapi32.INSTANCE.GetTokenInformation(phToken.getValue(),
WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, groups,
tokenInformationLength.getValue(), tokenInformationLength));
assertTrue(tokenInformationLength.getValue() > 0);
assertTrue(groups.GroupCount > 0);
for (SID_AND_ATTRIBUTES sidAndAttribute : groups.getGroups()) {
assertTrue(Advapi32.INSTANCE.IsValidSid(sidAndAttribute.Sid));
// System.out.println(Advapi32Util.convertSidToStringSid(sidAndAttribute.Sid));
}
} finally {
Kernel32Util.closeHandleRef(phToken);
}
}
public void testImpersonateLoggedOnUser() {
USER_INFO_1 userInfo = new USER_INFO_1();
userInfo.usri1_name = "JNAAdvapi32TestImp";
userInfo.usri1_password = "!JNAP$$Wrd0";
userInfo.usri1_priv = LMAccess.USER_PRIV_USER;
// ignore test if not able to add user (need to be administrator to do this).
if (LMErr.NERR_Success != Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null)) {
return;
}
try {
HANDLEByReference phUser = new HANDLEByReference();
try {
assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name.toString(),
null, userInfo.usri1_password.toString(), WinBase.LOGON32_LOGON_NETWORK,
WinBase.LOGON32_PROVIDER_DEFAULT, phUser));
assertTrue(Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser.getValue()));
assertTrue(Advapi32.INSTANCE.RevertToSelf());
} finally {
HANDLE hUser = phUser.getValue();
if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) {
Kernel32Util.closeHandle(hUser);
}
}
} finally {
assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel(
null, userInfo.usri1_name.toString()));
}
}
public void testRegOpenKeyEx() {
HKEYByReference phKey = new HKEYByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft", 0, WinNT.KEY_READ, phKey));
assertTrue(WinBase.INVALID_HANDLE_VALUE != phKey.getValue());
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegQueryValueEx() {
HKEYByReference phKey = new HKEYByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, WinNT.KEY_READ, phKey));
IntByReference lpcbData = new IntByReference();
IntByReference lpType = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phKey.getValue(), "User Agent", 0, lpType, (char[]) null, lpcbData));
assertEquals(WinNT.REG_SZ, lpType.getValue());
assertTrue(lpcbData.getValue() > 0);
char[] buffer = new char[lpcbData.getValue()];
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phKey.getValue(), "User Agent", 0, lpType, buffer, lpcbData));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegDeleteValue() {
assertEquals(W32Errors.ERROR_FILE_NOT_FOUND, Advapi32.INSTANCE.RegDeleteValue(
WinReg.HKEY_CURRENT_USER, "JNAAdvapi32TestDoesntExist"));
}
public void testRegSetValueEx_REG_SZ() {
HKEYByReference phKey = new HKEYByReference();
// create parent key
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software", 0, WinNT.KEY_WRITE | WinNT.KEY_READ, phKey));
HKEYByReference phkTest = new HKEYByReference();
IntByReference lpdwDisposition = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCreateKeyEx(
phKey.getValue(), "JNAAdvapi32Test", 0, null, 0, WinNT.KEY_ALL_ACCESS,
null, phkTest, lpdwDisposition));
// write a REG_SZ value
char[] lpData = Native.toCharArray("Test");
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegSetValueEx(
phkTest.getValue(), "REG_SZ", 0, WinNT.REG_SZ, lpData, lpData.length * 2));
// re-read the REG_SZ value
IntByReference lpType = new IntByReference();
IntByReference lpcbData = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phkTest.getValue(), "REG_SZ", 0, lpType, (char[]) null, lpcbData));
assertEquals(WinNT.REG_SZ, lpType.getValue());
assertTrue(lpcbData.getValue() > 0);
char[] buffer = new char[lpcbData.getValue()];
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phkTest.getValue(), "REG_SZ", 0, lpType, buffer, lpcbData));
assertEquals("Test", Native.toString(buffer));
// delete the test key
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(
phkTest.getValue()));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegDeleteKey(
phKey.getValue(), "JNAAdvapi32Test"));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegSetValueEx_DWORD() {
HKEYByReference phKey = new HKEYByReference();
// create parent key
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software", 0, WinNT.KEY_WRITE | WinNT.KEY_READ, phKey));
HKEYByReference phkTest = new HKEYByReference();
IntByReference lpdwDisposition = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCreateKeyEx(
phKey.getValue(), "JNAAdvapi32Test", 0, null, 0, WinNT.KEY_ALL_ACCESS,
null, phkTest, lpdwDisposition));
// write a REG_DWORD value
int value = 42145;
byte[] data = new byte[4];
data[0] = (byte)(value & 0xff);
data[1] = (byte)((value >> 8) & 0xff);
data[2] = (byte)((value >> 16) & 0xff);
data[3] = (byte)((value >> 24) & 0xff);
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegSetValueEx(
phkTest.getValue(), "DWORD", 0, WinNT.REG_DWORD, data, 4));
// re-read the REG_DWORD value
IntByReference lpType = new IntByReference();
IntByReference lpcbData = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phkTest.getValue(), "DWORD", 0, lpType, (char[]) null, lpcbData));
assertEquals(WinNT.REG_DWORD, lpType.getValue());
assertEquals(4, lpcbData.getValue());
IntByReference valueRead = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryValueEx(
phkTest.getValue(), "DWORD", 0, lpType, valueRead, lpcbData));
assertEquals(value, valueRead.getValue());
// delete the test key
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(
phkTest.getValue()));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegDeleteKey(
phKey.getValue(), "JNAAdvapi32Test"));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegCreateKeyEx() {
HKEYByReference phKey = new HKEYByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software", 0, WinNT.KEY_WRITE | WinNT.KEY_READ, phKey));
HKEYByReference phkResult = new HKEYByReference();
IntByReference lpdwDisposition = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCreateKeyEx(
phKey.getValue(), "JNAAdvapi32Test", 0, null, 0, WinNT.KEY_ALL_ACCESS,
null, phkResult, lpdwDisposition));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phkResult.getValue()));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegDeleteKey(
phKey.getValue(), "JNAAdvapi32Test"));
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegDeleteKey() {
assertEquals(W32Errors.ERROR_FILE_NOT_FOUND, Advapi32.INSTANCE.RegDeleteKey(
WinReg.HKEY_CURRENT_USER, "JNAAdvapi32TestDoesntExist"));
}
public void testRegEnumKeyEx() {
HKEYByReference phKey = new HKEYByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
0, WinNT.KEY_READ, phKey));
IntByReference lpcSubKeys = new IntByReference();
IntByReference lpcMaxSubKeyLen = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryInfoKey(
phKey.getValue(), null, null, null, lpcSubKeys, lpcMaxSubKeyLen, null, null,
null, null, null, null));
char[] name = new char[lpcMaxSubKeyLen.getValue() + 1];
for (int i = 0; i < lpcSubKeys.getValue(); i++) {
IntByReference lpcchValueName = new IntByReference(lpcMaxSubKeyLen.getValue() + 1);
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegEnumKeyEx(
phKey.getValue(), i, name, lpcchValueName, null, null, null, null));
assertEquals(Native.toString(name).length(), lpcchValueName.getValue());
}
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegEnumValue() {
HKEYByReference phKey = new HKEYByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegOpenKeyEx(
WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
0, WinNT.KEY_READ, phKey));
IntByReference lpcValues = new IntByReference();
IntByReference lpcMaxValueNameLen = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryInfoKey(
phKey.getValue(), null, null, null, null, null, null, lpcValues,
lpcMaxValueNameLen, null, null, null));
char[] name = new char[lpcMaxValueNameLen.getValue() + 1];
for (int i = 0; i < lpcValues.getValue(); i++) {
IntByReference lpcchValueName = new IntByReference(lpcMaxValueNameLen.getValue() + 1);
IntByReference lpType = new IntByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegEnumValue(
phKey.getValue(), i, name, lpcchValueName, null,
lpType, null, null));
assertEquals(Native.toString(name).length(), lpcchValueName.getValue());
}
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegCloseKey(phKey.getValue()));
}
public void testRegQueryInfoKey() {
IntByReference lpcClass = new IntByReference();
IntByReference lpcSubKeys = new IntByReference();
IntByReference lpcMaxSubKeyLen = new IntByReference();
IntByReference lpcValues = new IntByReference();
IntByReference lpcMaxClassLen = new IntByReference();
IntByReference lpcMaxValueNameLen = new IntByReference();
IntByReference lpcMaxValueLen = new IntByReference();
IntByReference lpcbSecurityDescriptor = new IntByReference();
FILETIME lpftLastWriteTime = new FILETIME();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.RegQueryInfoKey(
WinReg.HKEY_LOCAL_MACHINE, null, lpcClass, null,
lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues,
lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor,
lpftLastWriteTime));
assertTrue(lpcSubKeys.getValue() > 0);
}
public void testIsWellKnownSid() {
String sidString = EVERYONE;
PSIDByReference sid = new PSIDByReference();
assertTrue("sid conversion failed", Advapi32.INSTANCE.ConvertStringSidToSid(sidString, sid));
PSID value = sid.getValue();
try {
assertTrue("Not a world sid", Advapi32.INSTANCE.IsWellKnownSid(value, WELL_KNOWN_SID_TYPE.WinWorldSid));
assertFalse("Unexpected admin sid", Advapi32.INSTANCE.IsWellKnownSid(value, WELL_KNOWN_SID_TYPE.WinAccountAdministratorSid));
} finally {
Kernel32Util.freeLocalMemory(value.getPointer());
}
}
public void testCreateWellKnownSid() {
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinWorldSid, null, pSid, cbSid));
assertTrue("Not recognized as well-known SID",
Advapi32.INSTANCE.IsWellKnownSid(pSid, WELL_KNOWN_SID_TYPE.WinWorldSid));
assertTrue("Invalid SID size", cbSid.getValue() <= WinNT.SECURITY_MAX_SID_SIZE);
PointerByReference convertedSidStringPtr = new PointerByReference();
assertTrue("Failed to convert SID", Advapi32.INSTANCE.ConvertSidToStringSid(pSid, convertedSidStringPtr));
Pointer conv = convertedSidStringPtr.getValue();
try {
String convertedSidString = conv.getWideString(0);
assertEquals("Mismatched SID string", EVERYONE, convertedSidString);
} finally {
Kernel32Util.freeLocalMemory(conv);
}
}
public void testInitializeSecurityDescriptor() {
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION));
}
public void testSetGetSecurityDescriptorControl() {
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION));
assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorControl(sd, (short)WinNT.SE_DACL_PROTECTED, (short)WinNT.SE_DACL_PROTECTED));
ShortByReference pControl = new ShortByReference();
IntByReference lpdwRevision = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorControl(sd, pControl, lpdwRevision));
assertTrue(pControl.getValue() == WinNT.SE_DACL_PROTECTED);
assertTrue(lpdwRevision.getValue() == WinNT.SECURITY_DESCRIPTOR_REVISION);
}
public void testSetGetSecurityDescriptorOwner() {
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION));
PSID pSidPut = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSidPut, cbSid));
assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorOwner(sd, pSidPut, true));
BOOLByReference lpbOwnerDefaulted = new BOOLByReference();
PSIDByReference prSd = new PSIDByReference();
assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorOwner(sd, prSd, lpbOwnerDefaulted));
PSID pSidGet = prSd.getValue();
assertTrue(Advapi32.INSTANCE.EqualSid(pSidPut, pSidGet));
}
public void testSetGetSecurityDescriptorGroup() {
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION));
PSID pSidPut = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSidPut, cbSid));
assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorGroup(sd, pSidPut, true));
BOOLByReference lpbOwnerDefaulted = new BOOLByReference();
PSIDByReference prSd = new PSIDByReference();
assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorGroup(sd, prSd, lpbOwnerDefaulted));
PSID pSidGet = prSd.getValue();
assertTrue(Advapi32.INSTANCE.EqualSid(pSidPut, pSidGet));
}
public void testSetGetSecurityDescriptorDacl() throws IOException {
SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(sd, WinNT.SECURITY_DESCRIPTOR_REVISION));
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null);
cbAcl += (sidLength - DWORD.SIZE);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid));
assertTrue(Advapi32.INSTANCE.SetSecurityDescriptorDacl(sd, true, pAcl, false));
BOOLByReference lpbDaclPresent = new BOOLByReference();
BOOLByReference lpbDaclDefaulted = new BOOLByReference();
PACLByReference pDacl = new PACLByReference();
assertTrue(Advapi32.INSTANCE.GetSecurityDescriptorDacl(sd, lpbDaclPresent, pDacl, lpbDaclDefaulted));
ACL pAclGet = pDacl.getValue();
assertEquals(new BOOL(true), lpbDaclPresent.getValue());
assertEquals(new BOOL(false), lpbDaclDefaulted.getValue());
assertEquals(1, pAclGet.AceCount);
assertEquals(WinNT.ACL_REVISION, pAclGet.AclRevision);
}
public void testInitializeAcl() throws IOException {
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null);
cbAcl += (sidLength - DWORD.SIZE);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
}
public void testGetAce() throws IOException {
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null);
cbAcl += (sidLength - DWORD.SIZE);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid));
PointerByReference pAce = new PointerByReference(new Memory(16));
assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce));
ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue());
assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL);
assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid));
}
public void testAddAce() throws IOException {
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Advapi32Util.getAceSize(sidLength);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
ACCESS_ALLOWED_ACE pace = new ACCESS_ALLOWED_ACE(WinNT.STANDARD_RIGHTS_ALL,
WinNT.INHERITED_ACE,
pSid);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
assertTrue(Advapi32.INSTANCE.AddAce(pAcl, WinNT.ACL_REVISION, WinNT.MAXDWORD, pace.getPointer(), pace.size()));
PointerByReference pAce = new PointerByReference(new Memory(16));
assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce));
ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue());
assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL);
assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid));
}
public void testAddAccessAllowedAce() throws IOException {
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Advapi32Util.getAceSize(sidLength);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
assertTrue(Advapi32.INSTANCE.AddAccessAllowedAce(pAcl, WinNT.ACL_REVISION, WinNT.STANDARD_RIGHTS_ALL, pSid));
PointerByReference pAce = new PointerByReference(new Memory(16));
assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce));
ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue());
assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL);
assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid));
}
public void testAddAccessAllowedAceEx() throws IOException {
ACL pAcl;
int cbAcl = 0;
PSID pSid = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference cbSid = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue("Failed to create well-known SID",
Advapi32.INSTANCE.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, null, pSid, cbSid));
int sidLength = Advapi32.INSTANCE.GetLengthSid(pSid);
cbAcl = Native.getNativeSize(ACL.class, null);
cbAcl += Advapi32Util.getAceSize(sidLength);
cbAcl = Advapi32Util.alignOnDWORD(cbAcl);
pAcl = new ACL(cbAcl);
assertTrue(Advapi32.INSTANCE.InitializeAcl(pAcl, cbAcl, WinNT.ACL_REVISION));
assertTrue(Advapi32.INSTANCE.AddAccessAllowedAceEx(pAcl, WinNT.ACL_REVISION, WinNT.INHERIT_ONLY_ACE, WinNT.STANDARD_RIGHTS_ALL, pSid));
PointerByReference pAce = new PointerByReference(new Memory(16));
assertTrue(Advapi32.INSTANCE.GetAce(pAcl, 0, pAce));
ACCESS_ALLOWED_ACE pAceGet = new ACCESS_ALLOWED_ACE(pAce.getValue());
assertTrue(pAceGet.Mask == WinNT.STANDARD_RIGHTS_ALL);
assertTrue(Advapi32.INSTANCE.EqualSid(pAceGet.psid, pSid));
}
public void testOpenEventLog() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
assertNotNull(h);
assertFalse(h.equals(WinBase.INVALID_HANDLE_VALUE));
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
public void testRegisterEventSource() {
// the Security event log is reserved
HANDLE h = Advapi32.INSTANCE.RegisterEventSource(null, "Security");
assertNull(h);
assertEquals(W32Errors.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError());
}
public void testReportEvent() {
String applicationEventLog = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application";
String jnaEventSource = "JNADevEventSource";
String jnaEventSourceRegistryPath = applicationEventLog + "\\" + jnaEventSource;
// ignore test if not able to create key (need to be administrator to do this).
try {
final boolean keyCreated = Advapi32Util.registryCreateKey(WinReg.HKEY_LOCAL_MACHINE, jnaEventSourceRegistryPath);
if (!keyCreated) {
return;
}
} catch (Win32Exception e) {
return;
}
HANDLE h = Advapi32.INSTANCE.RegisterEventSource(null, jnaEventSource);
IntByReference before = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, before));
assertNotNull(h);
String s[] = { "JNA", "Event" };
Memory m = new Memory(4);
m.setByte(0, (byte) 1);
m.setByte(1, (byte) 2);
m.setByte(2, (byte) 3);
m.setByte(3, (byte) 4);
assertTrue(Advapi32.INSTANCE.ReportEvent(h, WinNT.EVENTLOG_ERROR_TYPE, 0, 0, null, 2, 4, s, m));
IntByReference after = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, after));
assertTrue(before.getValue() < after.getValue());
assertFalse(h.equals(WinBase.INVALID_HANDLE_VALUE));
assertTrue(Advapi32.INSTANCE.DeregisterEventSource(h));
Advapi32Util.registryDeleteKey(WinReg.HKEY_LOCAL_MACHINE, jnaEventSourceRegistryPath);
}
public void testGetNumberOfEventLogRecords() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
assertFalse(h.equals(WinBase.INVALID_HANDLE_VALUE));
IntByReference n = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, n));
assertTrue(n.getValue() >= 0);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
/*
public void testClearEventLog() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
assertFalse(h.equals(WinBase.INVALID_HANDLE_VALUE));
IntByReference before = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, before));
assertTrue(before.getValue() >= 0);
assertTrue(Advapi32.INSTANCE.ClearEventLog(h, null));
IntByReference after = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, after));
assertTrue(after.getValue() < before.getValue() || before.getValue() == 0);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
*/
public void testBackupEventLog() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
assertNotNull(h);
String backupFileName = Kernel32Util.getTempPath() + "\\JNADevEventLog.bak";
File f = new File(backupFileName);
if (f.exists()) {
f.delete();
}
assertTrue(Advapi32.INSTANCE.BackupEventLog(h, backupFileName));
HANDLE hBackup = Advapi32.INSTANCE.OpenBackupEventLog(null, backupFileName);
assertNotNull(hBackup);
IntByReference n = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetNumberOfEventLogRecords(hBackup, n));
assertTrue(n.getValue() >= 0);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
assertTrue(Advapi32.INSTANCE.CloseEventLog(hBackup));
}
public void testReadEventLog() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
IntByReference pnBytesRead = new IntByReference();
IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
Memory buffer = new Memory(1);
assertFalse(Advapi32.INSTANCE.ReadEventLog(h,
WinNT.EVENTLOG_SEQUENTIAL_READ | WinNT.EVENTLOG_BACKWARDS_READ,
0, buffer, (int) buffer.size(), pnBytesRead, pnMinNumberOfBytesNeeded));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
assertTrue(pnMinNumberOfBytesNeeded.getValue() > 0);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
public void testReadEventLogEntries() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
IntByReference pnBytesRead = new IntByReference();
IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
Memory buffer = new Memory(1024 * 64);
// shorten test, avoid iterating through all events
int maxReads = 3;
int rc = 0;
while(true) {
if (maxReads-- <= 0)
break;
if (! Advapi32.INSTANCE.ReadEventLog(h,
WinNT.EVENTLOG_SEQUENTIAL_READ | WinNT.EVENTLOG_FORWARDS_READ,
0, buffer, (int) buffer.size(), pnBytesRead, pnMinNumberOfBytesNeeded)) {
rc = Kernel32.INSTANCE.GetLastError();
if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
buffer = new Memory(pnMinNumberOfBytesNeeded.getValue());
rc = 0;
continue;
}
break;
}
int dwRead = pnBytesRead.getValue();
Pointer pevlr = buffer;
int maxRecords = 3;
while (dwRead > 0 && maxRecords-- > 0) {
EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
/*
System.out.println(record.RecordNumber.intValue()
+ " Event ID: " + record.EventID.intValue()
+ " Event Type: " + record.EventType.intValue()
+ " Event Source: " + pevlr.getString(record.size(), true));
*/
dwRead -= record.Length.intValue();
pevlr = pevlr.share(record.Length.intValue());
}
}
assertTrue("Unexpected error after reading event log: "
+ new Win32Exception(rc),
rc == W32Errors.ERROR_HANDLE_EOF || rc == 0);
assertTrue("Error closing event log",
Advapi32.INSTANCE.CloseEventLog(h));
}
public void testGetOldestEventLogRecord() {
HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, "Application");
IntByReference oldestRecord = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetOldestEventLogRecord(h, oldestRecord));
assertTrue(oldestRecord.getValue() >= 0);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
public void testQueryServiceStatusEx() {
SC_HANDLE scmHandle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(scmHandle);
SC_HANDLE serviceHandle = Advapi32.INSTANCE.OpenService(scmHandle, "eventlog", Winsvc.SERVICE_QUERY_STATUS);
assertNotNull(serviceHandle);
IntByReference pcbBytesNeeded = new IntByReference();
assertFalse(Advapi32.INSTANCE.QueryServiceStatusEx(serviceHandle, SC_STATUS_TYPE.SC_STATUS_PROCESS_INFO,
null, 0, pcbBytesNeeded));
assertEquals(W32Errors.ERROR_INSUFFICIENT_BUFFER, Kernel32.INSTANCE.GetLastError());
assertTrue(pcbBytesNeeded.getValue() > 0);
SERVICE_STATUS_PROCESS status = new SERVICE_STATUS_PROCESS(pcbBytesNeeded.getValue());
assertTrue(Advapi32.INSTANCE.QueryServiceStatusEx(serviceHandle, SC_STATUS_TYPE.SC_STATUS_PROCESS_INFO,
status, status.size(), pcbBytesNeeded));
assertTrue(status.dwCurrentState == Winsvc.SERVICE_STOPPED ||
status.dwCurrentState == Winsvc.SERVICE_RUNNING);
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(serviceHandle));
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(scmHandle));
}
public void testControlService() {
SC_HANDLE scmHandle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(scmHandle);
SC_HANDLE serviceHandle = Advapi32.INSTANCE.OpenService(scmHandle, "eventlog", Winsvc.SERVICE_QUERY_CONFIG);
assertNotNull(serviceHandle);
Winsvc.SERVICE_STATUS serverStatus = new Winsvc.SERVICE_STATUS();
assertNotNull(serviceHandle);
assertFalse(Advapi32.INSTANCE.ControlService(serviceHandle, Winsvc.SERVICE_CONTROL_STOP, serverStatus));
assertEquals(W32Errors.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError());
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(serviceHandle));
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(scmHandle));
}
public void testStartService() {
SC_HANDLE scmHandle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(scmHandle);
SC_HANDLE serviceHandle = Advapi32.INSTANCE.OpenService(scmHandle, "eventlog", Winsvc.SERVICE_QUERY_CONFIG);
assertNotNull(serviceHandle);
assertFalse(Advapi32.INSTANCE.StartService(serviceHandle, 0, null));
assertEquals(W32Errors.ERROR_ACCESS_DENIED, Kernel32.INSTANCE.GetLastError());
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(serviceHandle));
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(scmHandle));
}
public void testOpenService() {
assertNull(Advapi32.INSTANCE.OpenService(null, "eventlog", Winsvc.SERVICE_QUERY_CONFIG ));
assertEquals(W32Errors.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError());
SC_HANDLE scmHandle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(scmHandle);
SC_HANDLE serviceHandle = Advapi32.INSTANCE.OpenService(scmHandle, "eventlog", Winsvc.SERVICE_QUERY_CONFIG );
assertNotNull(serviceHandle);
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(serviceHandle));
assertNull(Advapi32.INSTANCE.OpenService(scmHandle, "slashesArentValidChars/", Winsvc.SERVICE_QUERY_CONFIG ));
assertEquals(W32Errors.ERROR_INVALID_NAME, Kernel32.INSTANCE.GetLastError());
assertNull(Advapi32.INSTANCE.OpenService(scmHandle, "serviceDoesNotExist", Winsvc.SERVICE_QUERY_CONFIG ));
assertEquals(W32Errors.ERROR_SERVICE_DOES_NOT_EXIST, Kernel32.INSTANCE.GetLastError());
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(scmHandle));
}
public void testOpenSCManager() {
SC_HANDLE handle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(handle);
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(handle));
assertNull(Advapi32.INSTANCE.OpenSCManager("invalidMachineName", null, Winsvc.SC_MANAGER_CONNECT));
int err = Kernel32.INSTANCE.GetLastError();
assertTrue("Unexpected error in OpenSCManager: " + err,
err == W32Errors.RPC_S_SERVER_UNAVAILABLE
|| err == W32Errors.RPC_S_INVALID_NET_ADDR);
assertNull(Advapi32.INSTANCE.OpenSCManager(null, "invalidDatabase", Winsvc.SC_MANAGER_CONNECT));
assertEquals(W32Errors.ERROR_INVALID_NAME, Kernel32.INSTANCE.GetLastError());
}
public void testCloseServiceHandle() throws Exception {
SC_HANDLE handle = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_CONNECT);
assertNotNull(handle);
assertTrue(Advapi32.INSTANCE.CloseServiceHandle(handle));
assertFalse(Advapi32.INSTANCE.CloseServiceHandle(null));
assertEquals(W32Errors.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError());
}
public void testCreateProcessAsUser() {
HANDLEByReference hToken = new HANDLEByReference();
HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(processHandle,
WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, hToken));
try {
assertFalse(Advapi32.INSTANCE.CreateProcessAsUser(hToken.getValue(), null, "InvalidCmdLine.jna",
null, null, false, 0, null, null, new WinBase.STARTUPINFO(),
new WinBase.PROCESS_INFORMATION()));
assertEquals(W32Errors.ERROR_FILE_NOT_FOUND, Kernel32.INSTANCE.GetLastError());
} finally {
Kernel32Util.closeHandleRef(hToken);
}
}
/**
* Tests both {@link Advapi32#LookupPrivilegeValue} and {@link Advapi32#LookupPrivilegeName}
*/
public void testLookupPrivilegeValueAndLookupPrivilegeName() {
WinNT.LUID luid = new WinNT.LUID();
assertFalse(Advapi32.INSTANCE.LookupPrivilegeValue(null, "InvalidName", luid));
assertEquals(Kernel32.INSTANCE.GetLastError(), W32Errors.ERROR_NO_SUCH_PRIVILEGE);
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_BACKUP_NAME, luid));
assertTrue(luid.LowPart > 0 || luid.HighPart > 0);
char[] lpName = new char[256];
IntByReference cchName = new IntByReference(lpName.length);
assertTrue(Advapi32.INSTANCE.LookupPrivilegeName(null, luid, lpName, cchName));
assertEquals(WinNT.SE_BACKUP_NAME.length(), cchName.getValue());
assertEquals(WinNT.SE_BACKUP_NAME, Native.toString(lpName));
}
public void testAdjustTokenPrivileges() {
HANDLEByReference hToken = new HANDLEByReference();
assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, hToken));
try {
// Find an already enabled privilege
TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(1024);
IntByReference returnLength = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetTokenInformation(hToken.getValue(), WinNT.TOKEN_INFORMATION_CLASS.TokenPrivileges,
tp, tp.size(), returnLength));
assertTrue(tp.PrivilegeCount.intValue() > 0);
WinNT.LUID luid = null;
for (int i=0; i<tp.PrivilegeCount.intValue(); i++) {
if ((tp.Privileges[i].Attributes.intValue() & WinNT.SE_PRIVILEGE_ENABLED) > 0) {
luid = tp.Privileges[i].Luid;
}
}
assertTrue(luid != null);
// Re-enable it. That should succeed.
tp = new WinNT.TOKEN_PRIVILEGES(1);
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tp, 0, null, null));
} finally {
Kernel32Util.closeHandleRef(hToken);
}
}
public void testImpersonateSelf() {
assertTrue(Advapi32.INSTANCE.ImpersonateSelf(WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous));
assertTrue(Advapi32.INSTANCE.RevertToSelf());
}
public void testGetSetFileSecurityNoSACL() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
int memSize = 64 * 1024;
Memory memorySecurity = new Memory(memSize);
IntByReference sizeNeeded = new IntByReference(0);
// create a temp file
File file = createTempFile();
String filePath = file.getAbsolutePath();
try {
assertEquals("GetFileSecurity(" + filePath + ")", true,
Advapi32.INSTANCE.GetFileSecurity(
filePath,
infoType,
memorySecurity,
memSize,
sizeNeeded));
assertEquals("SetFileSecurity(" + filePath + ")", true,
Advapi32.INSTANCE.SetFileSecurity(
filePath,
infoType,
memorySecurity));
} finally {
file.delete();
}
}
public void testGetSetSecurityInfoNoSACL() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
// create a temp file
File file = createTempFile();
String filePath = file.getAbsolutePath();
HANDLE hFile = Kernel32.INSTANCE.CreateFile(
filePath,
WinNT.GENERIC_ALL | WinNT.WRITE_OWNER | WinNT.WRITE_DAC,
WinNT.FILE_SHARE_READ,
new WinBase.SECURITY_ATTRIBUTES(),
WinNT.OPEN_EXISTING,
WinNT.FILE_ATTRIBUTE_NORMAL,
null);
assertFalse("Failed to create file handle: " + filePath, WinBase.INVALID_HANDLE_VALUE.equals(hFile));
try {
try {
assertEquals("GetSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.GetSecurityInfo(
hFile,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
null,
ppSecurityDescriptor));
assertEquals("SetSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.SetSecurityInfo(
hFile,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner.getValue(),
ppsidGroup.getValue(),
ppDacl.getValue(),
null));
} finally {
Kernel32.INSTANCE.CloseHandle(hFile);
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
}
public void testGetSetSecurityInfoForFileWithSACL() throws Exception {
boolean impersontating = false;
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDuplicate = new HANDLEByReference();
try {
// open thread or process token, elevate
if (!Advapi32.INSTANCE.OpenThreadToken(
Kernel32.INSTANCE.GetCurrentThread(),
TOKEN_ADJUST_PRIVILEGES,
false,
phToken))
{
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
// OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens,
// we need to open the process token to duplicate it, then set our thread token.
assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken));
// Process token opened, now duplicate
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(
phToken.getValue(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE,
null,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenImpersonation,
phTokenDuplicate));
// And set thread token.
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue()));
impersontating = true;
}
// Which token to adjust depends on whether we had to impersonate or not.
HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue();
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
WinNT.LUID pLuid = new WinNT.LUID();
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid));
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_RESTORE_NAME, pLuid));
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
// create a temp file
File file = createTempFile();
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
String filePath = file.getAbsolutePath();
HANDLE hFile = WinBase.INVALID_HANDLE_VALUE;
try {
try {
hFile = Kernel32.INSTANCE.CreateFile(
filePath,
WinNT.ACCESS_SYSTEM_SECURITY | WinNT.GENERIC_WRITE | WinNT.WRITE_OWNER | WinNT.WRITE_DAC,
WinNT.FILE_SHARE_READ,
new WinBase.SECURITY_ATTRIBUTES(),
WinNT.OPEN_EXISTING,
WinNT.FILE_ATTRIBUTE_NORMAL,
null);
assertEquals("GetSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.GetSecurityInfo(
hFile,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
ppSacl,
ppSecurityDescriptor));
assertEquals("SetSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.SetSecurityInfo(
hFile,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner.getValue(),
ppsidGroup.getValue(),
ppDacl.getValue(),
ppSacl.getValue()));
} finally {
if (hFile != WinBase.INVALID_HANDLE_VALUE)
Kernel32.INSTANCE.CloseHandle(hFile);
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
if (impersontating) {
assertTrue("SetThreadToken", Advapi32.INSTANCE.SetThreadToken(null, null));
}
else {
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0));
assertTrue("AdjustTokenPrivileges", Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
}
} finally {
Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate);
}
}
public void testGetNamedSecurityInfoForFileNoSACL() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
File file = createTempFile();
try {
try {
assertEquals("GetNamedSecurityInfo(" + file + ")", 0,
Advapi32.INSTANCE.GetNamedSecurityInfo(
file.getAbsolutePath(),
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
null,
ppSecurityDescriptor));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
}
public void testGetNamedSecurityInfoForFileWithSACL() throws Exception {
boolean impersontating = false;
WinNT.LUID pLuid = new WinNT.LUID();
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid));
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDuplicate = new HANDLEByReference();
try {
// open thread or process token, elevate
if (!Advapi32.INSTANCE.OpenThreadToken(
Kernel32.INSTANCE.GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, false, phToken))
{
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
// OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens,
// we need to open the process token to duplicate it, then set our thread token.
assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken));
// Process token opened, now duplicate
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(phToken.getValue(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE,
null,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenImpersonation,
phTokenDuplicate));
// And set thread token.
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue()));
impersontating = true;
}
// Which token to adjust depends on whether we had to impersonate or not.
HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue();
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
File file = createTempFile();
String filePath = file.getAbsolutePath();
try {
try {
assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.GetNamedSecurityInfo(
filePath,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
ppSacl,
ppSecurityDescriptor));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
if (impersontating) {
Advapi32.INSTANCE.SetThreadToken(null, null);
}
else {
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0));
Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null);
}
} finally {
Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate);
}
}
public void testSetNamedSecurityInfoForFileNoSACL() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
// create a temp file
File file = createTempFile();
String filePath = file.getAbsolutePath();
try {
try {
assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.GetNamedSecurityInfo(
filePath,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
null,
ppSecurityDescriptor));
assertEquals("SetNamedSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.SetNamedSecurityInfo(
filePath,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner.getValue(),
ppsidGroup.getValue(),
ppDacl.getValue(),
null));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
}
public void testSetNamedSecurityInfoForFileWithSACL() throws Exception {
boolean impersontating = false;
HANDLEByReference phToken = new HANDLEByReference();
HANDLEByReference phTokenDuplicate = new HANDLEByReference();
try {
// open thread or process token, elevate
if (!Advapi32.INSTANCE.OpenThreadToken(
Kernel32.INSTANCE.GetCurrentThread(),
TOKEN_ADJUST_PRIVILEGES,
false,
phToken))
{
assertEquals(W32Errors.ERROR_NO_TOKEN, Kernel32.INSTANCE.GetLastError());
// OpenThreadToken may fail with W32Errors.ERROR_NO_TOKEN if current thread is anonymous. When this happens,
// we need to open the process token to duplicate it, then set our thread token.
assertTrue(Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), TOKEN_DUPLICATE, phToken));
// Process token opened, now duplicate
assertTrue(Advapi32.INSTANCE.DuplicateTokenEx(
phToken.getValue(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE,
null,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenImpersonation,
phTokenDuplicate));
// And set thread token.
assertTrue(Advapi32.INSTANCE.SetThreadToken(null, phTokenDuplicate.getValue()));
impersontating = true;
}
// Which token to adjust depends on whether we had to impersonate or not.
HANDLE tokenAdjust = impersontating ? phTokenDuplicate.getValue() : phToken.getValue();
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
WinNT.LUID pLuid = new WinNT.LUID();
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_SECURITY_NAME, pLuid));
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
assertTrue(Advapi32.INSTANCE.LookupPrivilegeValue(null, SE_RESTORE_NAME, pLuid));
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
assertTrue(Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
// create a temp file
File file = createTempFile();
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION;
PointerByReference ppsidOwner = new PointerByReference();
PointerByReference ppsidGroup = new PointerByReference();
PointerByReference ppDacl = new PointerByReference();
PointerByReference ppSacl = new PointerByReference();
PointerByReference ppSecurityDescriptor = new PointerByReference();
String filePath = file.getAbsolutePath();
try {
try {
assertEquals("GetNamedSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.GetNamedSecurityInfo(
filePath,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner,
ppsidGroup,
ppDacl,
ppSacl,
ppSecurityDescriptor));
// Send the DACL as a SACL
assertEquals("SetNamedSecurityInfo(" + filePath + ")", 0,
Advapi32.INSTANCE.SetNamedSecurityInfo(
filePath,
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
ppsidOwner.getValue(),
ppsidGroup.getValue(),
ppDacl.getValue(),
ppDacl.getValue()));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
if (impersontating) {
assertTrue("SetThreadToken", Advapi32.INSTANCE.SetThreadToken(null, null));
}
else {
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(pLuid, new DWORD(0));
assertTrue("AdjustTokenPrivileges", Advapi32.INSTANCE.AdjustTokenPrivileges(tokenAdjust, false, tp, 0, null, null));
}
} finally {
Kernel32Util.closeHandleRefs(phToken, phTokenDuplicate);
}
}
public void testGetSecurityDescriptorLength() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference ppSecurityDescriptor = new PointerByReference();
File file = createTempFile();
try {
try {
assertEquals("GetNamedSecurityInfo(" + file + ")", 0,
Advapi32.INSTANCE.GetNamedSecurityInfo(
file.getAbsolutePath(),
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
null,
null,
null,
null,
ppSecurityDescriptor));
assertTrue("GetSecurityDescriptorLength(" + file + ")",
Advapi32.INSTANCE.GetSecurityDescriptorLength(ppSecurityDescriptor.getValue()) > 0);
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
}
public void testIsValidSecurityDescriptor() throws Exception {
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference ppSecurityDescriptor = new PointerByReference();
File file = createTempFile();
try {
try {
assertEquals("GetNamedSecurityInfo(" + file + ")",
Advapi32.INSTANCE.GetNamedSecurityInfo(
file.getAbsolutePath(),
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
null,
null,
null,
null,
ppSecurityDescriptor), 0);
assertTrue("IsValidSecurityDescriptor(" + file + ")",
Advapi32.INSTANCE.IsValidSecurityDescriptor(ppSecurityDescriptor.getValue()));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(ppSecurityDescriptor.getValue());
}
}
public void testMakeSelfRelativeSD() {
SECURITY_DESCRIPTOR absolute = new SECURITY_DESCRIPTOR(64 * 1024);
assertTrue(Advapi32.INSTANCE.InitializeSecurityDescriptor(absolute, WinNT.SECURITY_DESCRIPTOR_REVISION));
SECURITY_DESCRIPTOR_RELATIVE relative = new SECURITY_DESCRIPTOR_RELATIVE(64 * 1024);
IntByReference lpdwBufferLength = new IntByReference(64 * 1024);
assertTrue(Advapi32.INSTANCE.MakeSelfRelativeSD(absolute, relative, lpdwBufferLength));
assertEquals(WinNT.SECURITY_DESCRIPTOR_REVISION, relative.Revision);
}
public void testMakeAbsoluteSD() throws Exception {
SECURITY_DESCRIPTOR absolute = new SECURITY_DESCRIPTOR(64 * 1024);
// Get a SD in self relative form
int infoType = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION;
PointerByReference relativeByReference = new PointerByReference();
File file = createTempFile();
try {
try {
assertEquals("GetNamedSecurityInfo(" + file + ")",
Advapi32.INSTANCE.GetNamedSecurityInfo(
file.getAbsolutePath(),
AccCtrl.SE_OBJECT_TYPE.SE_FILE_OBJECT,
infoType,
null,
null,
null,
null,
relativeByReference), 0);
SECURITY_DESCRIPTOR_RELATIVE relative = new SECURITY_DESCRIPTOR_RELATIVE(relativeByReference.getValue());
PSID pOwner = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
PSID pGroup = new PSID(WinNT.SECURITY_MAX_SID_SIZE);
ACL pDacl = new ACL(ACL.MAX_ACL_SIZE);
ACL pSacl = new ACL(ACL.MAX_ACL_SIZE);
IntByReference lpdwBufferLength = new IntByReference(absolute.size());
IntByReference lpdwDaclSize = new IntByReference(ACL.MAX_ACL_SIZE);
IntByReference lpdwSaclSize= new IntByReference(ACL.MAX_ACL_SIZE);
IntByReference lpdwOwnerSize= new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
IntByReference lpdwPrimaryGroupSize = new IntByReference(WinNT.SECURITY_MAX_SID_SIZE);
assertTrue(Advapi32.INSTANCE.MakeAbsoluteSD(relative, absolute, lpdwBufferLength, pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize, pGroup, lpdwPrimaryGroupSize));
} finally {
file.delete();
}
} finally {
Kernel32Util.freeLocalMemory(relativeByReference.getValue());
}
}
public void testMapGenericReadMask() {
final GENERIC_MAPPING mapping = new GENERIC_MAPPING();
mapping.genericRead = new DWORD(FILE_GENERIC_READ);
mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE);
mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE);
mapping.genericAll = new DWORD(FILE_ALL_ACCESS);
final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_READ));
Advapi32.INSTANCE.MapGenericMask(rights, mapping);
assertEquals(FILE_GENERIC_READ, rights.getValue().intValue());
assertTrue(GENERIC_READ != (rights.getValue().intValue() & GENERIC_READ));
}
public void testMapGenericWriteMask() {
final GENERIC_MAPPING mapping = new GENERIC_MAPPING();
mapping.genericRead = new DWORD(FILE_GENERIC_READ);
mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE);
mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE);
mapping.genericAll = new DWORD(FILE_ALL_ACCESS);
final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_WRITE));
Advapi32.INSTANCE.MapGenericMask(rights, mapping);
assertEquals(FILE_GENERIC_WRITE, rights.getValue().intValue());
assertTrue(GENERIC_WRITE != (rights.getValue().intValue() & GENERIC_WRITE));
}
public void testMapGenericExecuteMask() {
final GENERIC_MAPPING mapping = new GENERIC_MAPPING();
mapping.genericRead = new DWORD(FILE_GENERIC_READ);
mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE);
mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE);
mapping.genericAll = new DWORD(FILE_ALL_ACCESS);
final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_EXECUTE));
Advapi32.INSTANCE.MapGenericMask(rights, mapping);
assertEquals(FILE_GENERIC_EXECUTE, rights.getValue().intValue());
assertTrue(GENERIC_EXECUTE != (rights.getValue().intValue() & GENERIC_EXECUTE));
}
public void testMapGenericAllMask() {
final GENERIC_MAPPING mapping = new GENERIC_MAPPING();
mapping.genericRead = new DWORD(FILE_GENERIC_READ);
mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE);
mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE);
mapping.genericAll = new DWORD(FILE_ALL_ACCESS);
final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_ALL));
Advapi32.INSTANCE.MapGenericMask(rights, mapping);
assertEquals(FILE_ALL_ACCESS, rights.getValue().intValue());
assertTrue(GENERIC_ALL != (rights.getValue().intValue() & GENERIC_ALL));
}
public void testAccessCheck() {
final GENERIC_MAPPING mapping = new GENERIC_MAPPING();
mapping.genericRead = new DWORD(FILE_GENERIC_READ);
mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE);
mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE);
mapping.genericAll = new DWORD(FILE_ALL_ACCESS);
final Memory securityDescriptorMemoryPointer = new Memory(1);
final PRIVILEGE_SET privileges = new PRIVILEGE_SET(1);
privileges.PrivilegeCount = new DWORD(0);
final DWORDByReference privilegeLength = new DWORDByReference(new DWORD(privileges.size()));
final DWORDByReference grantedAccess = new DWORDByReference();
final BOOLByReference result = new BOOLByReference();
final boolean status = Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, null, new DWORD(FILE_GENERIC_READ), mapping, privileges, privilegeLength, grantedAccess, result);
assertFalse(status);
assertFalse(result.getValue().booleanValue());
assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError());
}
public void testEncryptFile() throws Exception {
// create a temp file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
// encrypt a read only file
file.setWritable(false);
assertFalse(Advapi32.INSTANCE.EncryptFile(lpFileName));
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());
// encrypt a writable file
file.setWritable(true);
assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName));
file.delete();
}
public void testDecryptFile() throws Exception {
// create an encrypted file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName));
// decrypt a read only file
file.setWritable(false);
assertFalse(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
assertEquals(WinError.ERROR_FILE_READ_ONLY, Kernel32.INSTANCE.GetLastError());
// decrypt
file.setWritable(true);
assertTrue(Advapi32.INSTANCE.DecryptFile(lpFileName, new DWORD(0)));
file.delete();
}
public void testFileEncryptionStatus() throws Exception {
DWORDByReference lpStatus = new DWORDByReference();
// create a temp file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
// unencrypted file
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, lpStatus));
assertEquals(FILE_ENCRYPTABLE, lpStatus.getValue().intValue());
// read only file
file.setWritable(false);
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, lpStatus));
assertEquals(FILE_READ_ONLY, lpStatus.getValue().intValue());
// encrypted file
file.setWritable(true);
assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName));
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(lpFileName, lpStatus));
assertEquals(FILE_IS_ENCRYPTED, lpStatus.getValue().intValue());
file.delete();
}
public void testEncryptionDisable() throws Exception {
DWORDByReference lpStatus = new DWORDByReference();
// create a temp dir
String filePath = System.getProperty("java.io.tmpdir") + File.separator +
System.nanoTime();
String DirPath = filePath;
File dir = new File(filePath);
dir.mkdir();
// check status
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(DirPath, lpStatus));
assertEquals(FILE_ENCRYPTABLE, lpStatus.getValue().intValue());
// disable encryption
assertTrue(Advapi32.INSTANCE.EncryptionDisable(DirPath, true));
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(DirPath, lpStatus));
assertEquals(FILE_DIR_DISALOWED, lpStatus.getValue().intValue());
// enable encryption
assertTrue(Advapi32.INSTANCE.EncryptionDisable(DirPath, false));
assertTrue(Advapi32.INSTANCE.FileEncryptionStatus(DirPath, lpStatus));
assertEquals(FILE_ENCRYPTABLE, lpStatus.getValue().intValue());
// clean up
for (File file : dir.listFiles()) {
file.delete();
}
dir.delete();
}
public void testOpenEncryptedFileRaw() throws Exception {
// create an encrypted file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName));
// open file for export
ULONG ulFlags = new ULONG(0);
PointerByReference pvContext = new PointerByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw(
lpFileName, ulFlags, pvContext));
Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue());
file.delete();
}
public void testReadEncryptedFileRaw() throws Exception {
// create an encrypted file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
assertTrue("EncryptFile(" + lpFileName + ")", Advapi32.INSTANCE.EncryptFile(lpFileName));
// open file for export
ULONG ulFlags = new ULONG(0);
PointerByReference pvContext = new PointerByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw(
lpFileName, ulFlags, pvContext));
// read encrypted file
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() {
@Override
public DWORD callback(Pointer pbData, Pointer
pvCallbackContext, ULONG ulLength) {
if (pbData == null) {
throw new NullPointerException("Callback data unexpectedly missing");
}
byte[] arr = pbData.getByteArray(0, ulLength.intValue());
try {
outputStream.write(arr);
} catch (IOException e) {
throw new RuntimeException(e);
}
return new DWORD(W32Errors.ERROR_SUCCESS);
}
};
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.ReadEncryptedFileRaw(
pfExportCallback, null, pvContext.getValue()));
outputStream.close();
Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue());
file.delete();
}
public void testWriteEncryptedFileRaw() throws Exception {
// create an encrypted file
File file = createTempFile();
String lpFileName = file.getAbsolutePath();
assertTrue(Advapi32.INSTANCE.EncryptFile(lpFileName));
// open file for export
ULONG ulFlags = new ULONG(0);
PointerByReference pvContext = new PointerByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw(
lpFileName, ulFlags, pvContext));
// read encrypted file
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
FE_EXPORT_FUNC pfExportCallback = new FE_EXPORT_FUNC() {
@Override
public DWORD callback(Pointer pbData, Pointer
pvCallbackContext, ULONG ulLength) {
if (pbData == null) {
throw new NullPointerException("Callback data unexpectedly null");
}
byte[] arr = pbData.getByteArray(0, ulLength.intValue());
try {
outputStream.write(arr);
} catch (IOException e) {
throw new RuntimeException(e);
}
return new DWORD(W32Errors.ERROR_SUCCESS);
}
};
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.ReadEncryptedFileRaw(
pfExportCallback, null, pvContext.getValue()));
outputStream.close();
Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext.getValue());
// open file for import
String lbFileName2 = System.getProperty("java.io.tmpdir") +
File.separator + "backup-" + file.getName();
ULONG ulFlags2 = new ULONG(CREATE_FOR_IMPORT);
PointerByReference pvContext2 = new PointerByReference();
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.OpenEncryptedFileRaw(
lbFileName2, ulFlags2, pvContext2));
// write encrypted file
final IntByReference elementsReadWrapper = new IntByReference(0);
FE_IMPORT_FUNC pfImportCallback = new FE_IMPORT_FUNC() {
@Override
public DWORD callback(Pointer pbData, Pointer pvCallbackContext,
ULONGByReference ulLength) {
int elementsRead = elementsReadWrapper.getValue();
int remainingElements = outputStream.size() - elementsRead;
int length = Math.min(remainingElements, ulLength.getValue().intValue());
pbData.write(0, outputStream.toByteArray(), elementsRead, length);
elementsReadWrapper.setValue(elementsRead + length);
ulLength.setValue(new ULONG(length));
return new DWORD(W32Errors.ERROR_SUCCESS);
}
};
assertEquals(W32Errors.ERROR_SUCCESS, Advapi32.INSTANCE.WriteEncryptedFileRaw(
pfImportCallback, null, pvContext2.getValue()));
Advapi32.INSTANCE.CloseEncryptedFileRaw(pvContext2.getValue());
file.delete();
new File(lbFileName2.toString()).delete();
}
private File createTempFile() throws Exception {
String filePath = System.getProperty("java.io.tmpdir") + System.nanoTime()
+ ".text";
File file = new File(filePath);
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
for (int i = 0; i < 1000; i++) {
fileWriter.write("Sample text " + i + System.getProperty("line.separator"));
}
fileWriter.close();
return file;
}
public void testCreateProcessWithLogonW() {
String winDir = Kernel32Util.getEnvironmentVariable("WINDIR");
assertNotNull("No WINDIR value returned", winDir);
assertTrue("Specified WINDIR does not exist: " + winDir, new File(winDir).exists());
STARTUPINFO si = new STARTUPINFO();
si.lpDesktop = null;
PROCESS_INFORMATION results = new PROCESS_INFORMATION();
// i have the same combination on my luggage
boolean result = Advapi32.INSTANCE.CreateProcessWithLogonW("A" + System.currentTimeMillis(), "localhost", "12345", Advapi32.LOGON_WITH_PROFILE, new File(winDir, "notepad.exe").getAbsolutePath(), "", 0, null, "", si, results);
// we tried to run notepad as a bogus user, so it should fail.
assertFalse("CreateProcessWithLogonW should have returned false because the username was bogus.", result);
// should fail with "the user name or password is incorrect" (error 1326)
assertEquals("GetLastError() should have returned ERROR_LOGON_FAILURE because the username was bogus.", W32Errors.ERROR_LOGON_FAILURE, Native.getLastError());
}
}